#include "chatwindow.h"
#include "ui_chatwindow.h"
#include <QColorDialog>
#include <QJsonArray>
#include <QFileDialog>
#include <QPropertyAnimation>
#include <QKeyEvent>
#include <QMessageBox>
#include <QTextBrowser>

ChatWindow::ChatWindow(ClientNetwork *clientNet,QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ChatWindow),
    m_clientNetwork(clientNet)
{
    ui->setupUi(this);

    // 初始化字号下拉框
    for (int i = 8; i <= 28; i += 2) {
        ui->fontSizeCombo->addItem(QString::number(i));
    }
    ui->fontSizeCombo->setCurrentText("12");
    ui->chatDisplay->setOpenLinks(false); // 禁止自动打开链接
    // 初始化接收者下拉框为禁用状态(默认群聊)
    ui->receiverCombo->setEnabled(false);

    setupConnections();

    ui->onlineCountLabel->setText(QString("在线用户(%1)").arg(ui->userListWidget->count()));

    connect(m_clientNetwork, &ClientNetwork::privateMessageReceived,
            this, &ChatWindow::onPrivateMessageReceived);
    connect(m_clientNetwork, &ClientNetwork::groupMessageReceived,
            this, &ChatWindow::onGroupMessageReceived);

    connect(m_clientNetwork, &ClientNetwork::imageTransferReceived,
            this, [this](const QJsonObject &msg) {
                onTransferMessageReceived(msg, true);
            });
    connect(m_clientNetwork, &ClientNetwork::fileTransferReceived,
            this, [this](const QJsonObject &msg) {
                onTransferMessageReceived(msg, false);
            });

    connect(ui->chatDisplay, &QTextBrowser::anchorClicked,
            this, &ChatWindow::onAnchorClicked);
}

ChatWindow::~ChatWindow()
{
    delete ui;
}

void ChatWindow::setupConnections()
{
    // 字体设置
    connect(ui->fontCombo, &QFontComboBox::currentFontChanged, this, &ChatWindow::onFontChanged);
    connect(ui->fontSizeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ChatWindow::onFontSizeChanged);

    // 文本样式
    connect(ui->boldButton, &QToolButton::toggled, this, &ChatWindow::onBoldToggled);
    connect(ui->italicButton, &QToolButton::toggled, this, &ChatWindow::onItalicToggled);
    connect(ui->underlineButton, &QToolButton::toggled, this, &ChatWindow::onUnderlineToggled);
    connect(ui->colorButton, &QToolButton::clicked, this, &ChatWindow::onColorClicked);

    // 功能按钮
    connect(ui->emojiButton, &QToolButton::clicked, this, &ChatWindow::onEmojiClicked);
    connect(ui->imageButton, &QToolButton::clicked, this, &ChatWindow::onImageClicked);
    connect(ui->fileButton, &QToolButton::clicked, this, &ChatWindow::onFileClicked);
    connect(ui->sendButton, &QPushButton::clicked, this, &ChatWindow::onSendClicked);

    // 聊天模式切换
    connect(ui->chatModeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ChatWindow::onChatModeChanged);

    // 用户列表点击
    connect(ui->userListWidget, &QListWidget::itemClicked,
            this, &ChatWindow::onUserItemClicked);

    if (m_clientNetwork) {
        connect(m_clientNetwork, &ClientNetwork::onlineUsersUpdated,
                this, &ChatWindow::updateOnlineUsers);
    }
}

void ChatWindow::addUser(const QString &name, const QIcon &icon)
{
    QListWidgetItem *item = new QListWidgetItem(icon, name);
    item->setData(Qt::UserRole, name); // 存储用户名

    // 设置用户项样式
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setSizeHint(QSize(0, 30)); // 设置合适的高度

    ui->userListWidget->addItem(item);
}

// 以下是槽函数实现
void ChatWindow::onFontChanged(const QFont &font)
{
    ui->messageInput->setCurrentFont(font);
}

void ChatWindow::onFontSizeChanged(int index)
{
    int size = ui->fontSizeCombo->itemText(index).toInt();
    ui->messageInput->setFontPointSize(size);
}

void ChatWindow::onBoldToggled(bool checked)
{
    ui->messageInput->setFontWeight(checked ? QFont::Bold : QFont::Normal);
}

void ChatWindow::onItalicToggled(bool checked)
{
    ui->messageInput->setFontItalic(checked);
}

void ChatWindow::onUnderlineToggled(bool checked)
{
    ui->messageInput->setFontUnderline(checked);
}

void ChatWindow::onColorClicked()
{
    QColor color = QColorDialog::getColor(ui->messageInput->textColor(), this, "选择颜色");
    if (color.isValid()) {
        ui->messageInput->setTextColor(color);
    }
}

void ChatWindow::onEmojiClicked()
{
    // 实现表情选择对话框
}

void ChatWindow::onImageClicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, "选择图片", "",
                                                    "Images (*.png *.jpg *.jpeg *.bmp *.gif)");
    if (fileName.isEmpty()) return;

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this, "错误", "无法打开图片文件");
        return;
    }

    QByteArray imageData = file.readAll();
    file.close();

    QString sender = username;
    QString receiver;
    if (ui->chatModeCombo->currentText() == "私聊") {
        receiver = ui->receiverCombo->currentText();
        if (receiver.isEmpty()) {
            QMessageBox::warning(this, "错误", "请选择私聊对象");
            return;
        }
    } else {
        receiver = "所有人";
    }

    QFileInfo fileInfo(fileName);
    QByteArray message = MessageUtil::buildImageTransfer(
        sender, receiver, imageData, fileInfo.fileName());

    m_clientNetwork->sendMessage(message);

    // 在本地聊天窗口显示图片消息
    QImage image;
    image.loadFromData(imageData);
    displayImageMessage(sender, receiver, image, fileInfo.fileName(), true);
}

void ChatWindow::onFileClicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, "选择文件", "", "All Files (*.*)");
    if (fileName.isEmpty()) return;

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this, "错误", "无法打开文件");
        return;
    }

    QByteArray fileData = file.readAll();
    file.close();

    QString sender = username;
    QString receiver;
    if (ui->chatModeCombo->currentText() == "私聊") {
        receiver = ui->receiverCombo->currentText();
        if (receiver.isEmpty()) {
            QMessageBox::warning(this, "错误", "请选择私聊对象");
            return;
        }
    } else {
        receiver = "所有人";
    }

    QFileInfo fileInfo(fileName);
    QByteArray message = MessageUtil::buildFileTransfer(
        sender, receiver, fileData, fileInfo.fileName());

    m_clientNetwork->sendMessage(message);

    // 在本地聊天窗口显示文件消息
    displayFileMessage(sender, receiver, fileInfo.fileName(), file.size(), true);
}

void ChatWindow::shakeWindow()
{
    QPropertyAnimation *animation = new QPropertyAnimation(this, "pos");
    animation->setDuration(100);
    animation->setLoopCount(5);
    animation->setKeyValueAt(0, pos());
    animation->setKeyValueAt(0.1, pos() + QPoint(5, 5));
    animation->setKeyValueAt(0.2, pos() + QPoint(-5, -5));
    animation->setKeyValueAt(0.3, pos() + QPoint(5, 0));
    animation->setKeyValueAt(0.4, pos() + QPoint(-5, 0));
    animation->setKeyValueAt(0.5, pos() + QPoint(5, 5));
    animation->setKeyValueAt(0.6, pos() + QPoint(-5, -5));
    animation->setKeyValueAt(0.7, pos() + QPoint(5, 0));
    animation->setKeyValueAt(0.8, pos() + QPoint(-5, 0));
    animation->setKeyValueAt(0.9, pos() + QPoint(5, 5));
    animation->setKeyValueAt(1, pos());
    animation->start(QAbstractAnimation::DeleteWhenStopped);
}

void ChatWindow::onSendClicked()
{
    QString message = ui->messageInput->toPlainText().trimmed();
    if (message.isEmpty()) return;

    QString sender = username; // 当前登录用户
    QString mode = ui->chatModeCombo->currentText();
    QByteArray messageData;
    QString receiver;

    if (mode == "私聊") {
        // 私聊消息
        receiver = ui->receiverCombo->currentText();

        if (receiver.isEmpty()) {
            QMessageBox::warning(this, "错误", "请选择私聊对象");
            return;
        }

        messageData = MessageUtil::buildPrivateMessage(sender, receiver, message);

        // 添加到聊天显示 (私聊，是我发送的)
        appendMessageToChat(sender, receiver, message, QDateTime::currentDateTime(), true, true);
    } else {
        // 群聊消息
        messageData = MessageUtil::buildGroupMessage(sender, "所有人", message);

        // 添加到聊天显示 (群聊，是我发送的)
        appendMessageToChat(sender, "所有人", message, QDateTime::currentDateTime(), false, true);
    }

    // 通过网络发送消息
    if (m_clientNetwork) {
        m_clientNetwork->sendMessage(messageData);
    }

    ui->messageInput->clear();
    ui->messageInput->setFocus();
}

void ChatWindow::onPrivateMessageReceived(const QJsonObject &message)
{
    QString sender, receiver, content;
    qint64 timestamp;
    QString messageId;
    bool isFile, isImage;

    if (MessageUtil::parsePrivateMessage(message, sender, receiver, content,
                                         timestamp, messageId, isFile, isImage)) {
        // 显示接收到的私聊消息
        appendMessageToChat(sender, receiver, content,
                            QDateTime::fromMSecsSinceEpoch(timestamp),
                            true, false);
    }
}

void ChatWindow::onGroupMessageReceived(const QJsonObject &message)
{
    QString sender, groupId, content;
    qint64 timestamp;
    QString messageId;
    bool isFile, isImage;

    if (MessageUtil::parseGroupMessage(message, sender, groupId, content,
                                       timestamp, messageId, isFile, isImage)) {
        // 显示接收到的群聊消息 (固定显示"所有人")
        appendMessageToChat(sender, "所有人", content,
                            QDateTime::fromMSecsSinceEpoch(timestamp),
                            false, false);
    }
}

void ChatWindow::appendMessageToChat(const QString &sender,
                                     const QString &receiver,
                                     const QString &message,
                                     const QDateTime &timestamp,
                                     bool isPrivateChat,
                                     bool isMyMessage)
{
    QString displayText;
    QString timeStr = timestamp.toString("hh:mm:ss");

    if (isPrivateChat) {
        // 私聊消息样式
        if (isMyMessage) {
            displayText = QString("<div style='margin:5px; text-align:right;'>"
                                  "<span style='color:#1E90FF; font-weight:bold;'>"
                                  "我对 %1</span><br/>"
                                  "<div style='background:#DCF8C6; display:inline-block; "
                                  "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                                  "%2</div><br/>"
                                  "<span style='color:gray; font-size:small;'>%3</span>"
                                  "</div>")
                              .arg(receiver)
                              .arg(message)
                              .arg(timeStr);
        } else {
            displayText = QString("<div style='margin:5px; text-align:left;'>"
                                  "<span style='color:#FF4500; font-weight:bold;'>"
                                  "%1 对我</span><br/>"
                                  "<div style='background:#FFFFFF; display:inline-block; "
                                  "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                                  "%2</div><br/>"
                                  "<span style='color:gray; font-size:small;'>%3</span>"
                                  "</div>")
                              .arg(sender)
                              .arg(message)
                              .arg(timeStr);
        }
    } else {
        // 群聊消息样式
        if (isMyMessage) {
            displayText = QString("<div style='margin:5px; text-align:right;'>"
                                  "<span style='color:#1E90FF; font-weight:bold;'>"
                                  "我对 %1</span><br/>"
                                  "<div style='background:#DCF8C6; display:inline-block; "
                                  "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                                  "%2</div><br/>"
                                  "<span style='color:gray; font-size:small;'>%3</span>"
                                  "</div>")
                              .arg(receiver)
                              .arg(message)
                              .arg(timeStr);
        } else {
            displayText = QString("<div style='margin:5px; text-align:left;'>"
                                  "<span style='color:#FF4500; font-weight:bold;'>"
                                  "%1 对 %2</span><br/>"
                                  "<div style='background:#FFFFFF; display:inline-block; "
                                  "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                                  "%3</div><br/>"
                                  "<span style='color:gray; font-size:small;'>%4</span>"
                                  "</div>")
                              .arg(sender)
                              .arg(receiver)
                              .arg(message)
                              .arg(timeStr);
        }
    }

    QTextCursor cursor(ui->chatDisplay->textCursor());
    cursor.movePosition(QTextCursor::End);
    cursor.insertHtml(displayText);
    cursor.insertBlock();
    ui->chatDisplay->ensureCursorVisible();
}

void ChatWindow::updateOnlineUsers(const QJsonArray &users)
{
    // 清空当前用户列表
    ui->userListWidget->clear();
    ui->receiverCombo->clear();

    // 添加新用户
    for (const QJsonValue &user : users) {
        if (user.isObject()) {
            QJsonObject userObj = user.toObject();
            QString username = userObj["username"].toString();
            QString iconPath = userObj.value("icon").toString(":/icons/default_user.png");

            addUser(username, QIcon(iconPath));
        }
    }

    // 更新在线人数显示
    ui->onlineCountLabel->setText(QString("在线用户(%1)").arg(users.count()));

    // 如果当前是私聊模式，更新接收者下拉框
    if (ui->chatModeCombo->currentText() == "私聊") {
        for (int i = 0; i < ui->userListWidget->count(); ++i) {
            QListWidgetItem *item = ui->userListWidget->item(i);
            if(item->text()!=username)
            {
                ui->receiverCombo->addItem(item->icon(), item->text(), item->data(Qt::UserRole));
            }
        }
    }
}

void ChatWindow::onTransferMessageReceived(const QJsonObject &message, bool isImage)
{
    QString sender, receiver, fileName;
    QByteArray fileData;
    qint64 timestamp;
    QString fileType;
    shakeWindow();
    if (MessageUtil::parseTransferMessage(message, sender, receiver, fileData,
                                          fileName, timestamp, fileType)) {
        if (isImage) {
            QImage image;
            image.loadFromData(fileData);
            displayImageMessage(sender, receiver, image, fileName, false);

            // 可选：保存接收的图片
            saveReceivedImage(fileName, fileData);
        } else {
            displayFileMessage(sender, receiver, fileName, fileData.size(), false);

            //可选：弹出保存文件对话框
            saveReceivedFile(fileName, fileData);
        }
    }

}

void ChatWindow::displayImageMessage(const QString &sender, const QString &receiver,
                                     const QImage &image, const QString &fileName,
                                     bool isMyMessage)
{
    // 缩放图片以适应聊天窗口
    QPixmap pixmap = QPixmap::fromImage(image).scaled(300, 300, Qt::KeepAspectRatio);

    QString displayText;
    QString timeStr = QDateTime::currentDateTime().toString("hh:mm:ss");

    if (isMyMessage) {
        // 将 QImage 转换为 Base64
        QByteArray imageData;
        QBuffer buffer(&imageData);
        buffer.open(QIODevice::WriteOnly);
        image.save(&buffer, "PNG"); // 保存为 PNG 格式
        QString base64Image = QString::fromLatin1(imageData.toBase64());

        displayText = QString("<div style='margin:5px; text-align:right;'>"
                              "<span style='color:#1E90FF; font-weight:bold;'>"
                              "我对 %1 [图片]</span><br/>"
                              "<img src='data:image/png;base64,%2' width='%3' height='%4'/><br/>"
                              "<span style='color:gray; font-size:small;'>%5 - %6</span>"
                              "</div>")
                          .arg(receiver)
                          .arg(base64Image) // 使用转换后的 Base64 字符串
                          .arg(pixmap.width())
                          .arg(pixmap.height())
                          .arg(fileName)
                          .arg(timeStr);
    } else {
        // 同样的转换适用于 else 分支
        QByteArray imageData;
        QBuffer buffer(&imageData);
        buffer.open(QIODevice::WriteOnly);
        image.save(&buffer, "PNG");
        QString base64Image = QString::fromLatin1(imageData.toBase64());

        displayText = QString("<div style='margin:5px; text-align:left;'>"
                              "<span style='color:#FF4500; font-weight:bold;'>"
                              "%1 对我 [图片]</span><br/>"
                              "<img src='data:image/png;base64,%2' width='%3' height='%4'/><br/>"
                              "<span style='color:gray; font-size:small;'>%5 - %6</span>"
                              "</div>")
                          .arg(sender)
                          .arg(base64Image) // 使用转换后的 Base64 字符串
                          .arg(pixmap.width())
                          .arg(pixmap.height())
                          .arg(fileName)
                          .arg(timeStr);
    }

    QTextCursor cursor(ui->chatDisplay->textCursor());
    cursor.movePosition(QTextCursor::End);
    cursor.insertHtml(displayText);
    cursor.insertBlock();
    ui->chatDisplay->ensureCursorVisible();
}

void ChatWindow::displayFileMessage(const QString &sender, const QString &receiver,
                                    const QString &fileName, qint64 fileSize,
                                    bool isMyMessage)
{
    QString sizeStr;
    if (fileSize < 1024) {
        sizeStr = QString("%1 字节").arg(fileSize);
    } else if (fileSize < 1024 * 1024) {
        sizeStr = QString("%1 KB").arg(fileSize / 1024.0, 0, 'f', 1);
    } else {
        sizeStr = QString("%1 MB").arg(fileSize / (1024.0 * 1024.0), 0, 'f', 1);
    }

    QString displayText;
    QString timeStr = QDateTime::currentDateTime().toString("hh:mm:ss");

    if (isMyMessage) {
        displayText = QString("<div style='margin:5px; text-align:right;'>"
                              "<span style='color:#1E90FF; font-weight:bold;'>"
                              "我对 %1 [文件]</span><br/>"
                              "<div style='background:#DCF8C6; display:inline-block; "
                              "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                              "文件: %2 (%3)<br/>"
                              "<a href='save:%4' style='color:blue;'>点击保存</a>"
                              "</div><br/>"
                              "<span style='color:gray; font-size:small;'>%5</span>"
                              "</div>")
                          .arg(receiver)
                          .arg(fileName)
                          .arg(sizeStr)
                          .arg(fileName)
                          .arg(timeStr);
    } else {
        displayText = QString("<div style='margin:5px; text-align:left;'>"
                              "<span style='color:#FF4500; font-weight:bold;'>"
                              "%1 对我 [文件]</span><br/>"
                              "<div style='background:#FFFFFF; display:inline-block; "
                              "padding:5px 10px; border-radius:10px; max-width:70%;'>"
                              "文件: %2 (%3)<br/>"
                              "<a href='save:%4' style='color:blue;'>点击保存</a>"
                              "</div><br/>"
                              "<span style='color:gray; font-size:small;'>%5</span>"
                              "</div>")
                          .arg(sender)
                          .arg(fileName)
                          .arg(sizeStr)
                          .arg(fileName)
                          .arg(timeStr);
    }

    QTextCursor cursor(ui->chatDisplay->textCursor());
    cursor.movePosition(QTextCursor::End);
    cursor.insertHtml(displayText);
    cursor.insertBlock();
    ui->chatDisplay->ensureCursorVisible();
}

void ChatWindow::onAnchorClicked(const QUrl &link)
{
    if (link.scheme() == "save") {
        QString fileName = QFileDialog::getSaveFileName(this, "保存文件",
                                                        link.path(), "All Files (*.*)");
        if (!fileName.isEmpty()) {
            // 这里需要从缓存中获取文件数据
            saveFileToDisk(fileName, getCachedFileData(link.path()));
        }
    }
}

void ChatWindow::saveReceivedFile(const QString &fileName, const QByteArray &fileData)
{
    // 缓存文件数据
    cachedFiles[fileName] = fileData;
}

void ChatWindow::saveReceivedImage(const QString &fileName, const QByteArray &imageData)
{
    // 缓存图片数据
    cachedFiles[fileName] = imageData;
}

QByteArray ChatWindow::getCachedFileData(const QString &fileName)
{
    return cachedFiles.value(fileName);
}

void ChatWindow::saveFileToDisk(const QString &fileName, const QByteArray &data)
{
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly)) {
        file.write(data);
        file.close();
        QMessageBox::information(this, "成功", "文件保存成功");
    } else {
        QMessageBox::warning(this, "错误", "无法保存文件");
    }
}

void ChatWindow::onChatModeChanged(int index)
{
    bool isPrivate = ui->chatModeCombo->currentText() == "私聊";
    ui->receiverCombo->setEnabled(isPrivate);

    if (isPrivate) {
        // 更新私聊对象列表
        ui->receiverCombo->clear();
        for (int i = 0; i < ui->userListWidget->count(); ++i) {
            QListWidgetItem *item = ui->userListWidget->item(i);
            if(item->text()!=username)
            {
                ui->receiverCombo->addItem(item->icon(), item->text(), item->data(Qt::UserRole));
            }
        }
    }
}

void ChatWindow::onUserItemClicked(QListWidgetItem *item)
{
    ui->chatModeCombo->setCurrentIndex(1); // 切换到私聊模式
    ui->receiverCombo->setCurrentText(item->text());
}
